package com.kapcb.mybatis.plus;

import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.kapcb.common.constant.PropertiesConstant;
import com.kapcb.common.constant.StringPool;
import com.kapcb.mybatis.plus.handler.MyBatisPlusMetaObjectHandler;
import com.kapcb.mybatis.plus.interceptor.MyBatisProperties;
import com.kapcb.mybatis.plus.interceptor.MyBatisSlowQueryLogInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.plugin.Interceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * <a>Title: MyBatisPlusAutoConfiguration </a>
 * <a>Author: kapcb <a>
 * <a>Description: MyBatisPlusAutoConfiguration <a>
 *
 * @author Kpacb
 * @version 1.0
 * @date 2024/6/14 20:48
 * @since 1.0
 */
@Slf4j
@Configuration
@EnableConfigurationProperties(value = MyBatisProperties.class)
public class MyBatisPlusAutoConfiguration {

    private final MyBatisProperties myBatisProperties;

    public MyBatisPlusAutoConfiguration(MyBatisProperties myBatisProperties) {
        this.myBatisProperties = myBatisProperties;
    }

    /**
     * 自动注册 MyBatis Plus 相关拦截器组件
     *
     * @return a {@link MybatisPlusInterceptor} object
     */
    @Bean("mybatisPlusInterceptor")
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        if (log.isDebugEnabled()) {
            log.debug("begin load mybatisPlusInterceptor into IOC ......");
        }
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        if (myBatisProperties.isEnablePagination()) {
            if (log.isDebugEnabled()) {
                log.debug("add PaginationInnerInterceptor");
            }
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(myBatisProperties.getDbType()));
        }
        // 乐观锁插件
        if (myBatisProperties.isEnableOptimisticLocker()) {
            if (log.isDebugEnabled()) {
                log.debug("add OptimisticLockerInnerInterceptor");
            }
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        }
        // 防全表更新与删除插件，默认拦截不带条件的删除、更新操作
        if (myBatisProperties.isEnableBlockAttack()) {
            if (log.isDebugEnabled()) {
                log.debug("add BlockAttackInnerInterceptor");
            }
            interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        }
        return interceptor;
    }

    /**
     * 慢查询 SQL 日志打印，默认关闭
     *
     * @return a {@link Interceptor}
     */
    @Bean("mybatisSlowQueryLogInterceptor")
    @ConditionalOnMissingBean(name = "mybatisSlowQueryLogInterceptor")
    @ConditionalOnProperty(prefix = PropertiesConstant.PROPERTIES_PREFIX + ".mybatis.slowQueryLog", name = StringPool.ENABLE, havingValue = StringPool.TRUE)
    public ConfigurationCustomizer mybatisSlowQueryLogInterceptor() {
        if (log.isDebugEnabled()) {
            log.debug("begin load mybatisSlowQueryLogInterceptor into IOC ......");
        }
        return configuration -> configuration.addInterceptor(new MyBatisSlowQueryLogInterceptor());
    }

    @Bean
    @ConditionalOnMissingBean(value = MetaObjectHandler.class)
    public MetaObjectHandler myBatisPlusMetaObjectHandler() {
        if (log.isDebugEnabled()) {
            log.debug("begin load myBatisPlusMetaObjectHandler into IOC ......");
        }
        return new MyBatisPlusMetaObjectHandler(myBatisProperties);
    }

    /**
     * 初始化表对象处理器
     */
//    @Bean
//    public PostInitTableInfoHandler postInitTableInfoHandler() {
//        return new PlusPostInitTableInfoHandler();
//    }
}
